Rabbit 2000 Peripherals


The Rabbit 2000 has a slave port, but enabling the slave port to use the slave port internal registers as the master device dedicates parallel port A for the slave port's data. This might be OK if the PIC's Parallel Slave Port (PSP) was fully compatible, but it is not addressable. The PIC has a single register for reads and a single register for writes. So instead of wiring the PIC as a slave device to the Rabbit, I'm going to wire it as a I/O device that is connected to the Rabbit data bus. If we latch some address lines on the falling edge of the cycle, the PIC can implement multiple devices. This has problems on device reads, since the PIC must completely service the read by the end of the cycle. One way to deal with this is with two reads; the first to get the data loaded in the PSP register and the second to actually read it. A better way is a command and response protocol. For commands that write data, a write cycle follows the command. For commands that read data, a read cycle follows the command. Since all of the peripherals on the PIC are memory mapped, a simple PEEK and POKE mechanism allows access to all of the on chip peripherals. Banks 0 and 1 are directly accessible. Banks 2 and 3 require the IRP bit (STATUS<7>) to be set. Only the PIC on chip EEPROM is accessed from banks 2 and 3. The same mechanism supports software implemented devices like 1-Wire sensors and PWM R/C servos. An address in user RAM is used for a command code and additional addresses are used for data.


Parallel Slave Port access to a Microchip PIC microcontroller allows access to most of the peripherals on the PIC and allows access to software implemented interfaces via memory mapped variables.


The simplest interface allows read and write access to the PIC memory space. This interface can be made robust by adding a signal that indicates whether the current write is an address or data. I’ll call this signal DATA_WR. It is a logic “1” for data writes and a logic “0” for address writes. Alternatives to using a DATA_WR signal requires timing to distinguish address from data.


The Rabbit 2000 data bus is 8 bits wide so external I/O cycles do a single IOWR or IORD strobe if the source or destination register is 8 bits wide and it does two IOWR or IORD strobes if the source or destination register is 16 bits wide.


External I/O chip select is driven by the alternate function of parallel port E. I’ve chosen port E bit 7 for my I/O chip select. The DATA_WR signal is driven by port E bit 0.


I’ve coded three types of peripheral devices that are implemented in software on the PIC. One is a PWM R/C servo driver. The second is a 1-Wire low level driver. The third is an I2C low level driver. The high level functionality is handled by the Rabbit 2000.





I'm going to use a PIC16F874 to implement a programmable I/O processor. This device has a Parallel Slave Port that looks like an 8 bit peripheral. I'll run it at about 1.38 MHz, clocked by the 11.059 MHz Rabbit crystal divided by 8.


I'm going to use Dallas Semiconductor DS18S20 temperature sensors. These are 1-Wire devices. We'll need the following functions: bit_read, bit_write, 1W-init, byte_read, byte_write, rom_ID, ID_measure_temp, ID_read_temp.


We'll also need EE_write to log data into the EEPROM. We'll need some way to interrogate the 1-Wire devices to discover their ID and and EE_read to read the data from the EEPROM when temperature logging is complete. The modes of operation will include configuration where 1-wire IDs are set, temperature logging, and data extraction.


The code on the PIC16F874 is simple. It implements the low level 1-Wire primitives and low level I2C or SPI primitives and provides access to these primitives via the Parallel Slave Port (PSP). It also implements PWM R/C servo control.


The code on the Rabbit does all the work. It is written in Forth.


The advantage of this partition is that each of these functions can be developed and tested independently.



| © 2005 Ken Staton